package com.stephen.bp.controller;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.stephen.bp.mapper.RecordMapper;
import com.stephen.bp.mapper.ScheduleMapper;
import com.stephen.bp.mapper.TeamMapper;
import com.stephen.bp.mapper.UserMapper;
import com.stephen.bp.model.Record;
import com.stephen.bp.model.Schedule;
import com.stephen.bp.model.Team;
import com.stephen.bp.model.User;
import com.stephen.bp.service.RoomService;
import com.stephen.bp.websocket.WebSocketServerHandler;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.*;

/**
 * @author qiuwenwei
 */
@Slf4j
@RestController
@AllArgsConstructor
public class Controller {
    private final UserMapper userMapper;
    private final RecordMapper recordMapper;
    private final TeamMapper teamMapper;
    private final ScheduleMapper scheduleMapper;
    private final RoomService roomService;

    @PostMapping("/getRunningRoom")
    public Object getRunningRoom(@RequestParam String username) {
        Map<String, Object> userInfo = new HashMap<>();
        Schedule runningSchedule = roomService.getRunningSchedule(username);
        userInfo.put("result", runningSchedule == null ? "error" : "ok");
        userInfo.put("schedule", runningSchedule);
        log.info("{}执行查询进行中的房间{}", username, runningSchedule == null ? null : JSONObject.toJSONString(runningSchedule));
        return userInfo;
    }


    @PostMapping("/login")
    public Object login(@RequestParam String loginName, @RequestParam String password) {
        Map<String, Object> userInfo = new HashMap<>();
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getLoginName, loginName);
        User user = userMapper.selectOne(queryWrapper);
        userInfo.put("result", user == null ? "error" : (user.getPassword().equals(password) ? "ok" : "error"));
        userInfo.put("user", user);
        log.info("{}执行页面登陆", user.getUsername());
        return userInfo;
    }

    @PostMapping("/record")
    public Object record(@RequestParam String username) {
        Map<String, Object> userInfo = new HashMap<>();
        LambdaQueryWrapper<Record> queryWrapper = new LambdaQueryWrapper<>();
        if (!username.startsWith("admin")) {
            queryWrapper.and(wq -> wq.eq(Record::getAUser, username).or().eq(Record::getBUser, username));
        }
        queryWrapper.orderByDesc(Record::getCreateTime);
        List<Record> records = recordMapper.selectList(queryWrapper);
        userInfo.put("result", "ok");
        userInfo.put("data", records);
        return userInfo;
    }

    @PostMapping("/record2")
    public Object record2(@RequestParam String username, @RequestParam String roomId) {
        Map<String, Object> userInfo = new HashMap<>();
        LambdaQueryWrapper<Record> queryWrapper = new LambdaQueryWrapper<>();
        if (!username.startsWith("admin")) {
            queryWrapper.and(wq -> wq.eq(Record::getAUser, username).or().eq(Record::getBUser, username));
        }
        if (roomId != null) {
            queryWrapper.eq(Record::getRoomId, roomId);
        }
        queryWrapper.orderByDesc(Record::getCreateTime);
        Record record = recordMapper.selectOne(queryWrapper);
        JSONObject object = record2Matchups2(record);
        userInfo.put("result", "ok");
        userInfo.put("data", object);
        return userInfo;
    }

    @PostMapping("/team")
    public Object team(@RequestParam String username) {
        Map<String, Object> teamInfo = new HashMap<>();
        if (!username.startsWith("admin")) {
            teamInfo.put("result", "error");
            return teamInfo;
        }
        LambdaQueryWrapper<Team> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(Team::getOrderNum);
        List<Team> records = teamMapper.selectList(queryWrapper);
        teamInfo.put("result", "ok");
        teamInfo.put("data", records);
        return teamInfo;
    }

    @PostMapping("/schedule")
    public Object schedule(@RequestParam String username) {
        Map<String, Object> teamInfo = new HashMap<>();
        LambdaQueryWrapper<Schedule> queryWrapper = new LambdaQueryWrapper<>();
        if (!username.startsWith("admin")) {
            queryWrapper.and(wq -> wq.eq(Schedule::getUser1, username).or().eq(Schedule::getUser2, username));
        }
        queryWrapper.orderByDesc(Schedule::getId);
        List<Schedule> records = scheduleMapper.selectList(queryWrapper);
        teamInfo.put("result", "ok");
        teamInfo.put("data", records);
        return teamInfo;
    }


    @PostMapping("/update/schedule")
    public Object update(@RequestBody Schedule schedule) {
        Map<String, Object> userInfo = new HashMap<>();
        if (schedule.getId() == null) {
            schedule.setRoomId(RoomService.generateRoomNumber());
            scheduleMapper.insert(schedule);
        } else {
            scheduleMapper.updateById(schedule);
        }
        userInfo.put("result", "ok");
        return userInfo;
    }

    @PostMapping("/user")
    public Object user(@RequestParam String username) {
        Map<String, Object> userInfo = new HashMap<>();
        if (!username.startsWith("admin")) {
            userInfo.put("result", "error");
            return userInfo;
        }
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        List<User> records = userMapper.selectList(queryWrapper);
        userInfo.put("result", "ok");
        userInfo.put("data", records);
        return userInfo;
    }

    @PostMapping("/update/user")
    public Object update(@RequestBody User user) {
        Map<String, Object> userInfo = new HashMap<>();
        if (user.getId() == null) {
            userMapper.insert(user);
        } else {
            userMapper.updateById(user);
        }
        userInfo.put("result", "ok");
        return userInfo;
    }

    @PostMapping("/update/team")
    public Object update(@RequestBody Team team) {
        Map<String, Object> userInfo = new HashMap<>();
        if (team.getId() == null) {
            teamMapper.insert(team);
        } else {
            teamMapper.updateById(team);
        }
        userInfo.put("result", "ok");
        return userInfo;
    }

    @GetMapping("/download")
    public void download(HttpServletResponse response) throws IOException {
        String outputFile = "BP结果.xlsx";

        // 创建工作簿和工作表
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("Matches");

        // 对阵信息、第一支球队信息、第二支球队信息、局数信息
        List<String[][]> matchupsList = new ArrayList<>();
        LambdaQueryWrapper<Record> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Record::getCreateTime);
        List<Record> recordList = recordMapper.selectList(queryWrapper);
        for (Record record : recordList) {
            matchupsList.add(record2Matchups(record));
        }
        // 如果有更多的matchups，继续添加到matchupsList中

        // 写入每个matchup信息
        int rowNum = 0;
        for (String[][] matchups : matchupsList) {
            for (int i = 0; i < matchups.length; i++) {
                Row row = sheet.createRow(rowNum++);
                for (int j = 0; j < matchups[i].length; j++) {
                    Cell cell = row.createCell(j);
                    cell.setCellValue(matchups[i][j]);
                    // 创建居中样式并应用于单元格
                    CellStyle style = workbook.createCellStyle();
                    style.setAlignment(HorizontalAlignment.CENTER);
                    cell.setCellStyle(style);
                }
            }
        }

        // 设置固定的列宽度
        int columnWidth = 256 * 20; // 20个字符的宽度
        for (int i = 0; i < matchupsList.get(0)[0].length; i++) {
            if (i == 2 || i == 4 || i == 7) {
                sheet.setColumnWidth(i, columnWidth / 4);
            } else {
                sheet.setColumnWidth(i, columnWidth);
            }
        }

        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(outputFile, StandardCharsets.UTF_8));
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        workbook.write(response.getOutputStream());
    }

    public static String[][] record2Matchups(Record record) {
        String[][] matchups = new String[][]{
                {"对阵", "{AUser}", "vs", "{BUser}", "", "对阵", "{AUser}", "vs", "{BUser}",},
                {"第一支球队", "{AUserS1}", "", "{BUserS1}", "", "第一局", "{AUserF1}", "", "{BUserF1}"},
                {"第二支球队", "{AUserS2}", "", "{BUserS2}", "", "第二局", "{AUserF2}", "", "{BUserF2}"},
                {"第三支球队", "{AUserS3}", "", "{BUserS3}", "", "第三局", "{AUserF3}", "", "{BUserF3}"},
                {"ban", "{AUserB1}", "", "{BUserB1}", "", "", "", ""},
                {"未选", "{AUserL1}", "", "{BUserL1}", "", "", "", ""},
                {"BP结束时间", "{Time}"},
                {""}
        };
        replaceContent(matchups, "{Time}", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(record.getCreateTime()));
        replaceContent(matchups, "{AUser}", record.getAUser());
        String[] a = record.getAResult().split("\n");
        String[] aUserS = a[1].split(":")[1].split(",");
        String[] aUserB = a[2].split(":")[1].split(",");
        String[] aUserF = a[3].split(":")[1].split(",");
        String[] aUserL = a[4].split(":")[1].split(",");

        replaceContent(matchups, "{AUserS1}", aUserS[0]);
        replaceContent(matchups, "{AUserS2}", aUserS[1]);
        replaceContent(matchups, "{AUserS3}", aUserS[2]);
        replaceContent(matchups, "{AUserF1}", aUserF[0]);
        replaceContent(matchups, "{AUserF2}", aUserF[1]);
        replaceContent(matchups, "{AUserF3}", aUserF[2]);
        replaceContent(matchups, "{AUserB1}", aUserB[0]);
        replaceContent(matchups, "{AUserL1}", aUserL[0]);


        replaceContent(matchups, "{BUser}", record.getBUser());

        String[] b = record.getBResult().split("\n");
        String[] bUserS = b[1].split(":")[1].split(",");
        String[] bUserB = b[2].split(":")[1].split(",");
        String[] bUserF = b[3].split(":")[1].split(",");
        String[] bUserL = b[4].split(":")[1].split(",");

        replaceContent(matchups, "{BUserS1}", bUserS[0]);
        replaceContent(matchups, "{BUserS2}", bUserS[1]);
        replaceContent(matchups, "{BUserS3}", bUserS[2]);
        replaceContent(matchups, "{BUserF1}", bUserF[0]);
        replaceContent(matchups, "{BUserF2}", bUserF[1]);
        replaceContent(matchups, "{BUserF3}", bUserF[2]);
        replaceContent(matchups, "{BUserB1}", bUserB[0]);
        replaceContent(matchups, "{BUserL1}", bUserL[0]);

        return matchups;
    }

    public static JSONObject record2Matchups2(Record record) {
        JSONObject data = new JSONObject();
        String[] a = record.getAResult().split("\n");
        String[] aUserB = a[2].split(":")[1].split(",");
        String[] aUserF = a[3].split(":")[1].split(",");
        String[] aUserL = a[4].split(":")[1].split(",");
        String[] b = record.getBResult().split("\n");
        String[] bUserB = b[2].split(":")[1].split(",");
        String[] bUserF = b[3].split(":")[1].split(",");
        String[] bUserL = b[4].split(":")[1].split(",");
        // 设置参数
        data.put("teamA", record.getAUser());
        data.put("teamB", record.getBUser());
        data.put("firstTeamA", aUserF[0]);
        data.put("firstTeamB", bUserF[0]);
        data.put("secondTeamA", aUserF[1]);
        data.put("secondTeamB", bUserF[1]);
        data.put("thirdTeamA", aUserF[2]);
        data.put("thirdTeamB", bUserF[2]);
        data.put("banA", aUserB[0]);
        data.put("banB", bUserB[0]);
        data.put("unselectedA", aUserL[0]);
        data.put("unselectedB", bUserL[0]);
        data.put("endTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(record.getCreateTime()));
        return data;
    }

    public static void replaceContent(String[][] matchups, String target, String replacement) {
        for (String[] matchup : matchups) {
            for (int i = 0; i < matchup.length; i++) {
                if (matchup[i].equals(target)) {
                    matchup[i] = replacement;
                }
            }
        }
    }

    @DeleteMapping("/clear")
    public void clear() {
        recordMapper.deleteAllRecords();
        scheduleMapper.deleteAllRecords();
    }

    @GetMapping("/info")
    public Object info() {
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("result", WebSocketServerHandler.start);
        return userInfo;
    }

    @GetMapping("/startOrStop")
    public Object startOrStop() {
        WebSocketServerHandler.start = !WebSocketServerHandler.start;
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("result", WebSocketServerHandler.start);
        log.info("BP{}", WebSocketServerHandler.start ? "开始" : "未开始");
        return userInfo;
    }
}
